🧠Почему context.WithCancel может вызвать утечку goroutine
context.WithCancel — удобный способ завершать операции, но если не вызывать cancel(), вы получите утечку. Причём не всегда это очевидно.
Посмотрим:
func handler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithCancel(r.Context()) // cancel не вызывается! go doSomething(ctx) w.Write([]byte("done")) }
func doSomething(ctx context.Context) { select { case <-time.After(10 * time.Second): fmt.Println("done work") case <-ctx.Done(): fmt.Println("canceled") } }
Что здесь не так?
Если handler завершится раньше, чем doSomething, и cancel() не вызван — doSomething останется висеть, пока не истечёт r.Context()илиtime.After. И таких горутин может накопиться много, особенно при высоких нагрузках.
💡 Как избежать
1. Всегда вызывай cancel(), когда используешь context.WithCancel, даже если кажется, что это «не нужно».
2. Если передаёшь контекст в goroutine — убедись, что она завершится, даже если вызывающая функция ушла.
context.WithCancel — мощный инструмент. Но без вызова cancel() ты легко создашь утечку, которую не поймаешь ни в логах, ни в профилях — только под нагрузкой.
🧠Почему context.WithCancel может вызвать утечку goroutine
context.WithCancel — удобный способ завершать операции, но если не вызывать cancel(), вы получите утечку. Причём не всегда это очевидно.
Посмотрим:
func handler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithCancel(r.Context()) // cancel не вызывается! go doSomething(ctx) w.Write([]byte("done")) }
func doSomething(ctx context.Context) { select { case <-time.After(10 * time.Second): fmt.Println("done work") case <-ctx.Done(): fmt.Println("canceled") } }
Что здесь не так?
Если handler завершится раньше, чем doSomething, и cancel() не вызван — doSomething останется висеть, пока не истечёт r.Context()илиtime.After. И таких горутин может накопиться много, особенно при высоких нагрузках.
💡 Как избежать
1. Всегда вызывай cancel(), когда используешь context.WithCancel, даже если кажется, что это «не нужно».
2. Если передаёшь контекст в goroutine — убедись, что она завершится, даже если вызывающая функция ушла.
context.WithCancel — мощный инструмент. Но без вызова cancel() ты легко создашь утечку, которую не поймаешь ни в логах, ни в профилях — только под нагрузкой.
Tata Power whose core business is to generate, transmit and distribute electricity has made no money to investors in the last one decade. That is a big blunder considering it is one of the largest power generation companies in the country. One of the reasons is the company's huge debt levels which stood at ₹43,559 crore at the end of March 2021 compared to the company’s market capitalisation of ₹44,447 crore.
Telegram auto-delete message, expiring invites, and more
elegram is updating its messaging app with options for auto-deleting messages, expiring invite links, and new unlimited groups, the company shared in a blog post. Much like Signal, Telegram received a burst of new users in the confusion over WhatsApp’s privacy policy and now the company is adopting features that were already part of its competitors’ apps, features which offer more security and privacy. Auto-deleting messages were already possible in Telegram’s encrypted Secret Chats, but this new update for iOS and Android adds the option to make messages disappear in any kind of chat. Auto-delete can be enabled inside of chats, and set to delete either 24 hours or seven days after messages are sent. Auto-delete won’t remove every message though; if a message was sent before the feature was turned on, it’ll stick around. Telegram’s competitors have had similar features: WhatsApp introduced a feature in 2020 and Signal has had disappearing messages since at least 2016.